<html>
<head><meta charset="utf-8"><title>Adding a HashMap literal — a can of worms · t-libs · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/index.html">t-libs</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html">Adding a HashMap literal — a can of worms</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="233483996"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233483996" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233483996">(Apr 07 2021 at 13:10)</a>:</h4>
<p>Since Rust 1.51, this is possible on stable:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">collections</span>::<span class="p">{</span><span class="n">BTreeMap</span><span class="p">,</span><span class="w"> </span><span class="n">BTreeSet</span><span class="p">,</span><span class="w"> </span><span class="n">HashMap</span><span class="p">,</span><span class="w"> </span><span class="n">HashSet</span><span class="p">};</span><span class="w"></span>

<span class="fm">macro_rules!</span><span class="w"> </span><span class="n">collection</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="c1">// map-like</span>
<span class="w">    </span><span class="p">(</span><span class="cp">$($k</span>:<span class="nc">expr</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="cp">$v</span>:<span class="nc">expr</span><span class="p">),</span><span class="o">*</span><span class="w"> </span><span class="cp">$(,</span><span class="p">)</span><span class="o">?</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">std</span>::<span class="n">iter</span>::<span class="nb">Iterator</span>::<span class="n">collect</span><span class="p">(</span><span class="n">std</span>::<span class="n">array</span>::<span class="n">IntoIter</span>::<span class="n">new</span><span class="p">([</span><span class="cp">$(</span><span class="p">(</span><span class="cp">$k</span><span class="p">,</span><span class="w"> </span><span class="cp">$v</span><span class="p">),)</span><span class="o">*</span><span class="p">]))</span><span class="w"></span>
<span class="w">    </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="c1">// set-like</span>
<span class="w">    </span><span class="p">(</span><span class="cp">$($v</span>:<span class="nc">expr</span><span class="p">),</span><span class="o">*</span><span class="w"> </span><span class="cp">$(,</span><span class="p">)</span><span class="o">?</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">std</span>::<span class="n">iter</span>::<span class="nb">Iterator</span>::<span class="n">collect</span><span class="p">(</span><span class="n">std</span>::<span class="n">array</span>::<span class="n">IntoIter</span>::<span class="n">new</span><span class="p">([</span><span class="cp">$($v</span><span class="p">,)</span><span class="o">*</span><span class="p">]))</span><span class="w"></span>
<span class="w">    </span><span class="p">};</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">s</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">_</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">collection</span><span class="o">!</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">s</span>: <span class="nc">BTreeSet</span><span class="o">&lt;</span><span class="n">_</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">collection</span><span class="o">!</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">s</span>: <span class="nc">HashSet</span><span class="o">&lt;</span><span class="n">_</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">collection</span><span class="o">!</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">s</span>: <span class="nc">BTreeMap</span><span class="o">&lt;</span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="n">_</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">collection</span><span class="o">!</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="p">);</span><span class="w"></span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">s</span>: <span class="nc">HashMap</span><span class="o">&lt;</span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="n">_</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">collection</span><span class="o">!</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Is it worth finally submitting a PR? This specific thing has had <a href="https://github.com/rust-lang/rfcs/issues/542">a _huge_ amount of bikeshedding</a>, so I understand if the team doesn't want to add it. It's just reasonably low cost now (and IMO any potential additional cost should try to be removed anyway).</p>



<a name="233520181"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233520181" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233520181">(Apr 07 2021 at 16:25)</a>:</h4>
<p>I think there are simpler, less bikesheddy first steps that can be taken, e.g. <code>impl&lt;K, V, const N: usize&gt; From&lt;[(K, V); N]&gt; for HashMap&lt;K, V&gt;</code> would allow a "constructor" such as:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">HashMap</span>::<span class="n">from</span><span class="p">([</span><span class="w"></span>
<span class="w">    </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w"></span>
<span class="p">)];</span><span class="w"></span>
</code></pre></div>
<p>there's plenty of precedence here, e.g. <code>String::from("foo")</code>, <code>Vec::from([1,2,3])</code>, so this should be supported regardless, and should be non-controversial</p>



<a name="233520874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233520874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233520874">(Apr 07 2021 at 16:29)</a>:</h4>
<p>That's a neat idea</p>



<a name="233521094"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233521094" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233521094">(Apr 07 2021 at 16:31)</a>:</h4>
<p>it should be a simple PR, I might try to file that today</p>



<a name="233521657"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233521657" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233521657">(Apr 07 2021 at 16:34)</a>:</h4>
<p><code>from_slice</code> maybe? Do we want to allow slices of unknown length?</p>



<a name="233521667"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233521667" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233521667">(Apr 07 2021 at 16:34)</a>:</h4>
<p>(sorry for adding to the bikeshed)</p>



<a name="233521721"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233521721" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233521721">(Apr 07 2021 at 16:35)</a>:</h4>
<p>This would need to use arrays rather than slices so we can move the values</p>



<a name="233522924"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233522924" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233522924">(Apr 07 2021 at 16:43)</a>:</h4>
<p>I would love to have the macro described, with exactly the syntax described. Name bikeshedding, perhaps, but the syntax and semantics look perfect to me.</p>



<a name="233523009"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233523009" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233523009">(Apr 07 2021 at 16:43)</a>:</h4>
<p>Having <code>from</code> seems great too, and in particular that also means into will work.</p>



<a name="233526191"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233526191" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233526191">(Apr 07 2021 at 17:03)</a>:</h4>
<p>I'll limit my bikeshedding to suggesting that it be <code>collect!</code> rather than <code>collection!</code>; it's supposed to be a convenience feature, so let it be a bit more convenient (and also describe the underlying operation more directly)</p>



<a name="233530892"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233530892" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233530892">(Apr 07 2021 at 17:35)</a>:</h4>
<p>Not a bad idea, though I can imagine people then thinking it's more general.</p>



<a name="233530900"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233530900" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233530900">(Apr 07 2021 at 17:35)</a>:</h4>
<p><span class="user-mention" data-user-id="256342">@bstrie</span> your example <del>already works, that's what the macro does, using <code>FromIterator::from_iter</code></del> almost already works (we don't have <code>IntoIterator</code> for arrays for the reasons we all know)</p>



<a name="233531383"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233531383" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233531383">(Apr 07 2021 at 17:38)</a>:</h4>
<p>So your functions would be reimplementing <code>FromIterator</code> functionality as I see it.</p>



<a name="233531646"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233531646" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233531646">(Apr 07 2021 at 17:40)</a>:</h4>
<p>Can you even implement <code>From</code>? Won't that run into <a href="https://stackoverflow.com/q/37347311/155423">How is there a conflicting implementation of <code>From</code> when using a generic type?</a></p>



<a name="233532298"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233532298" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233532298">(Apr 07 2021 at 17:45)</a>:</h4>
<p>The <code>from</code> / <code>from_iter</code> versions are a bit more annoying, syntax wise (<a href="https://github.com/rust-lang/rfcs/issues/542#issuecomment-576354291">https://github.com/rust-lang/rfcs/issues/542#issuecomment-576354291</a>)</p>



<a name="233532926"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233532926" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233532926">(Apr 07 2021 at 17:49)</a>:</h4>
<p>I do think it'd be nice to have that macro.  One thing I wonder: are there any concerns about it making the whole array on the stack?  It could also expand to <code>Default</code> + <code>extend_reserve(${count(pairs)})</code> + a bunch of <code>extend_one</code>s...</p>



<a name="233533826"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233533826" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233533826">(Apr 07 2021 at 17:54)</a>:</h4>
<p>It's a tradeoff: if all the elements are constants then we should codegen a constant array in .rodata and loop over that. However if the elements are dynamic then we are better off inserting each element one at a time.</p>



<a name="233535191"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233535191" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233535191">(Apr 07 2021 at 18:02)</a>:</h4>
<p>Has there been talk of an <code>is_constexpr</code> kind of thing?  I don't know how feasible it'd be to implement, but there's a couple places it'd be nice -- like adding an "are you actually only swapping one item" check in the <code>swap_nonoverlapping</code> code has come up before, but is probably not worth the effort to run at runtime.</p>



<a name="233535562"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233535562" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233535562">(Apr 07 2021 at 18:04)</a>:</h4>
<p>Actually, can the rodata approach even work for <code>Copy</code> things if what it needs is an <code>array::IntoIter&lt;f32, 1000&gt;</code>?  Seems like needing ownership, rather than just <code>&amp;'static</code> would make it hard...</p>



<a name="233568106"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233568106" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233568106">(Apr 07 2021 at 21:44)</a>:</h4>
<p>One potential downside of the suggested implementation is that <code>let x: Vec&lt;_&gt; = collect!(1 =&gt; 2, 3 =&gt; 4);</code> will work and produce a vector <code>[(1, 2), (3, 4)]</code>. Should this be prevented somehow?</p>



<a name="233568775"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233568775" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233568775">(Apr 07 2021 at 21:50)</a>:</h4>
<p>why would we want to prevent people from making a collection of tuples?</p>



<a name="233570983"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233570983" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233570983">(Apr 07 2021 at 22:08)</a>:</h4>
<p>I think it should be fine for <code>collect![(1, 2), (3, 4)]</code> to work, but <code>collect!(1 =&gt; 2, 3 =&gt; 4)</code> into something that's not a map-like seems like it's exposing implementation details</p>



<a name="233571124"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233571124" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233571124">(Apr 07 2021 at 22:09)</a>:</h4>
<p>For the converse, i.e. <code>let x: HashMap&lt;_, _&gt; = collect![(1, 2), (3, 4)]</code>, I think this is fine since <code>HashMap</code> is documented to collect iterators over pairs</p>



<a name="233571433"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233571433" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233571433">(Apr 07 2021 at 22:12)</a>:</h4>
<p>Without addressing whether it would be a good idea, one way to support this is to have a trait <code>trait CollectMap&lt;K, V&gt;: FromIterator&lt;(K, V)&gt; {}</code> which is implemented explicitly for things that want to support the <code>collect![1 =&gt; 2, 3 =&gt; 4]</code> syntax. That way, you would be able to collect into a hashmap but not a vector with this syntax, while <code>collect![(1, 2), (3, 4)]</code> would work for both</p>



<a name="233580135"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233580135" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233580135">(Apr 07 2021 at 23:42)</a>:</h4>
<p>I don't think it's an issue to document that <code>collect!(a =&gt; b, c =&gt; d)</code> works by way of tuples.</p>



<a name="233580167"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233580167" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233580167">(Apr 07 2021 at 23:42)</a>:</h4>
<p>I don't think hiding that implementation detail buys us anything.</p>



<a name="233580188"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233580188" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233580188">(Apr 07 2021 at 23:42)</a>:</h4>
<p>Tuples are our standard way of pairing two things together.</p>



<a name="233597749"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233597749" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233597749">(Apr 08 2021 at 03:54)</a>:</h4>
<p>Well, more than hiding implementation details, it's more like a type safety / clear code issue. It's weird to construct a non-map using a map-generating syntax, and even though it's possible for us to give it a meaning, it's more likely to be a typo or bug</p>



<a name="233597849"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233597849" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233597849">(Apr 08 2021 at 03:56)</a>:</h4>
<p>I don't feel particularly strongly about it, but I mention it since it is possible to defend against this kind of error and now is the time to do it if it is considered beneficial</p>



<a name="233597907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233597907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233597907">(Apr 08 2021 at 03:57)</a>:</h4>
<p>It feels vaguely like those kinds of soft typing conversions you find in JS like <code>1 + "2" = "12"</code></p>



<a name="233602854"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233602854" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233602854">(Apr 08 2021 at 05:15)</a>:</h4>
<blockquote>
<p>It's weird to construct a non-map using a map-generating syntax</p>
</blockquote>
<p>Note that the syntax would also allow you to specify non-unique keys which will obviously get discarded when building a map.</p>



<a name="233603290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233603290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233603290">(Apr 08 2021 at 05:22)</a>:</h4>
<p>There are two places you could address that issue:</p>
<ul>
<li>In the procedural macro, you can at least lint on duplicated keys of simple types like integers and strings, but in general you can't run the equality comparators, and I'm not sure but there might be false positives if something looks like a number but is actually coerced to a wrapper with a different kind of equality (Is this possible? I suspect no but I'm not 100%). Getting aggressive with errors here might be problematic though, especially if this gets used by some other macro that wants different error handling behavior.</li>
<li>At runtime (or const eval time), you can take note if any call to (the generalization of) <code>HashMap::insert</code> returns <code>Some(old)</code>. However it's not clear whether anything can be done about it unless the macro includes a catch block or something like that, so presumably the default behavior would either be to panic on duplicates or ignore them.</li>
</ul>



<a name="233607742"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233607742" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233607742">(Apr 08 2021 at 06:32)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms/near/233597749">said</a>:</p>
<blockquote>
<p>Well, more than hiding implementation details, it's more like a type safety / clear code issue. It's weird to construct a non-map using a map-generating syntax, and even though it's possible for us to give it a meaning, it's more likely to be a typo or bug</p>
</blockquote>
<p>If we called it <code>map!</code> or similar I'd agree, but if it's called <code>collect!</code>, it seems more reasonable for that to work.</p>



<a name="233714633"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233714633" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233714633">(Apr 08 2021 at 19:31)</a>:</h4>
<p>as a point of reference, in C++ it looks like:</p>
<div class="codehilite" data-code-language="C++"><pre><span></span><code><span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">foo</span> <span class="o">=</span> <span class="p">{</span>
        <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">},</span>
        <span class="p">{</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">}</span>
<span class="p">};</span>
</code></pre></div>
<p>which isn't to say that it's not possible to do better than C++, but I think I'd be more comfortable using the pre-existing tuple syntax rather than bikeshedding new faux-syntax</p>



<a name="233733319"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/233733319" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#233733319">(Apr 08 2021 at 21:26)</a>:</h4>
<p>&lt;nop&gt;</p>



<a name="234407137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/234407137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#234407137">(Apr 13 2021 at 21:44)</a>:</h4>
<p>it occurs to me that since macro namespacing works these days, perhaps associated macros could be a thing?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">HashMap</span>::<span class="n">new</span><span class="o">!</span><span class="p">{</span><span class="w"> </span><span class="mi">1</span>: <span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span>: <span class="mi">4</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
</code></pre></div>
<p>this would let users avoid <code>x: HashMap&lt;_, _&gt;</code>, and it would also prevent unintentional construction of Vecs via <code>=&gt;</code></p>



<a name="234420914"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/234420914" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#234420914">(Apr 14 2021 at 00:02)</a>:</h4>
<p><span class="user-mention" data-user-id="256342">@bstrie</span> That's a pretty huge can of worms.</p>



<a name="234421465"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/234421465" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#234421465">(Apr 14 2021 at 00:09)</a>:</h4>
<p>so sugary that they must be gummy worms</p>



<a name="234611701"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/234611701" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> XAMPPRocky <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#234611701">(Apr 15 2021 at 03:34)</a>:</h4>
<p>Also a benefit of a <code>collect!</code> macro in <code>std</code> would be that it works with any <code>FromIterator</code> type, including collection types in third party crates, where as namespaced macros would require every crate to implement their own macro constructor.</p>



<a name="234622700"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/219381-t-libs/topic/Adding%20a%20HashMap%20literal%20%E2%80%94%C2%A0a%20can%20of%20worms/near/234622700" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/219381-t-libs/topic/Adding.20a.20HashMap.20literal.20.E2.80.94.C2.A0a.20can.20of.20worms.html#234622700">(Apr 15 2021 at 06:18)</a>:</h4>
<p>we can put the macro in the hashmap module at least</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>